<?php

namespace Sharks\Core\Http;

use Sharks\Core\AppContext;
use Sharks\Core\Http\View\View;
use Sharks\Core\Support\Bag\ParameterBag;
use Sharks\Core\Support\Base\Arr;
use Sharks\Core\Support\Base\PropertiesReadOnly;

/**
 * 响应类
 */
class Response {

    /** @var 常用状态码 */
    const STATUS = [
        // Informational 1xx
        100 => 'Continue',
        101 => 'Switching Protocols',
        // Success 2xx
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        // Redirection 3xx
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Moved Temporarily ',  // 1.1
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        // 306 is deprecated but reserved
        307 => 'Temporary Redirect',
        // Client Error 4xx
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Timeout',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Request Entity Too Large',
        414 => 'Request-URI Too Long',
        415 => 'Unsupported Media Type',
        416 => 'Requested Range Not Satisfiable',
        417 => 'Expectation Failed',
        // Server Error 5xx
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Timeout',
        505 => 'HTTP Version Not Supported',
        509 => 'Bandwidth Limit Exceeded'
    ];

    private $view;
    private $header;
    private $statusCode;
    private $statusMsg;

    /** @app AppContext 全局唯一数据 */
    private $app;

    public function __construct(AppContext $app) {
        $this->app = $app;
        $this->statusCode = 200; // default status code is 200
        $this->statusMsg = self::STATUS[200];
        $this->header = new ParameterBag();
    }

    public function setHeader($header, $value) {
        header($header . ':' . $value);
    }

    public function setContentType($type) {
        $this->setHeader('Content-type', $type);
    }

    public function hasView() {
        return isset($this->view) && !is_null($this->view);
    }

    public function setView($view) {
        $this->view = $view;
    }

    public function status($statusCode, $statusMsg = null) {
        if (is_null($statusMsg)) {
            $statusMsg = self::STATUS[$statusCode];
        }

        $this->statusCode = $statusCode;
        $this->statusMsg = $statusMsg;
        header("HTTP/1.1 $statusCode $statusMsg");
    }

    /**
     * 向浏览器客户端发送响应内容
     */
    public function render() {
        ob_start();
        // set cookie
        foreach ($this->app->cookie()->responseCookie() as $name => $cookie) {
            setcookie($name, $cookie['value'], $cookie['expire'], $cookie['path'], $cookie['domain'], $cookie['secure']);
        }

        // response content
        if ($this->hasView()) {
            $this->view->render($this);
        }
        ob_end_flush();
    }

    public function app() {
        return $this->app;
    }
}